#include "notification.h"
#include "notification-displayer.h"


NotificationDisplayer::NotificationDisplayer (Notification* notification, int position, QObject* parent)
    : QThread(parent), notification(notification), position(position), showTime(5 + (position*4/5)), elapsed(0)
{
    moveToThread(this);

    connect (this, &NotificationDisplayer::setOpacity, notification, &Notification::setOpacity);
}


void NotificationDisplayer::run()
{
    beginFadingIn();
    exec();
}


void NotificationDisplayer::beginFadingIn()
{
    fadeInTimer = new QTimer(this);
    connect (fadeInTimer.data(), &QTimer::timeout, this, &NotificationDisplayer::fadeIn);
    fadeInTimer.data()->start(20);
}


void NotificationDisplayer::fadeIn()
{
    qreal opacityLevel = notification->getOpacity() + 0.05;
    emit setOpacity(opacityLevel);

    if (opacityLevel >= 1.00)
    {
        fadeInTimer.data()->stop();
        delete fadeInTimer.data();

        beginWaiting();
    }
}


void NotificationDisplayer::beginWaiting()
{
    if (waitTimer.isNull())
    {
        waitTimer = new QTimer(this);
        connect (waitTimer.data(), &QTimer::timeout, this, &NotificationDisplayer::checkElapsed);
    }

    waitTimer.data()->start(1000);
}


void NotificationDisplayer::checkElapsed()
{
    elapsed++;

    if (elapsed == showTime)
    {
        waitTimer.data()->stop();
        delete waitTimer.data();

        checkPosition();
    }
}


void NotificationDisplayer::checkPosition()
{
    if (position == 0)
        beginFadingOut();
}


void NotificationDisplayer::movingStarted()
{
    if (waitTimer != 0)
        waitTimer.data()->stop();
}


void NotificationDisplayer::movingEnded()
{
    if (fadeOutTimer != 0)
        return;

    position--;
}


void NotificationDisplayer::proceed()
{
    if (fadeInTimer != 0 || fadeOutTimer != 0)
        return;
    else if (waitTimer != 0)
    {
        if (waitTimer.data()->isActive())
            return;
    }

    if (elapsed < showTime)
        beginWaiting();
    else
        checkPosition();
}


void NotificationDisplayer::beginFadingOut()
{
    fadeOutTimer = new QTimer(this);
    connect (fadeOutTimer.data(), &QTimer::timeout, this, &NotificationDisplayer::fadeOut);
    emit fadingOutStarted(notification->height());
    fadeOutTimer.data()->start(20);
}


void NotificationDisplayer::fadeOut()
{
    qreal opacityLevel = notification->getOpacity() - 0.05;
    emit setOpacity(opacityLevel);

    if (opacityLevel <= 0.00)
    {
        fadeOutTimer.data()->stop();
        delete fadeOutTimer.data();

        emit close();
        notification = 0;

        quit();
    }
}


void NotificationDisplayer::quitRequest()
{
    delete fadeOutTimer.data();
    delete waitTimer.data();
    delete fadeInTimer.data();

    quit();
}
